import { BuildType, MapUnitType, PosInfo } from '../define/GameDefine';
import GameSet from '../define/GameSet';
import { MapUnit } from '../object/MapUnit';
import RandomTool from '../tool/RandomTool';
import SaveModel from './SaveModel';

export default class MapModel {
  public static _save: MapModel;
  public static get ins(): MapModel {
    if (!this._save) {
      this._save = new MapModel();
    }
    return this._save;
  }

  private mapData: MapUnit[][];
  public getMapData(): MapUnit[][] {
    return this.mapData;
  }

  /**
   * 
   */
  public initMapData(rows: number, cols: number) {
    this.mapData = [];
    let ranPool: { [key: string]: MapUnit } = {};
    //初始化数据
    let ranData1: string[] = []; //建筑数据
    let ranData2: string[] = []; //障碍数据
    let randomRemain = {};
    for (let i: number = 0; i < rows; i++) {
      if (!this.mapData[i]) this.mapData[i] = [];
      for (let j: number = 0; j < cols; j++) {
        let mapUnit: MapUnit = new MapUnit(i, j);
        this.mapData[i].push(mapUnit);
        let key: string = `${i}_${j}`;
        ranPool[key] = mapUnit;
        if (i != rows - 1 && j != cols - 1) {
          ranData1.push(key);
          randomRemain[key] = 1;
        } else {
          ranData2.push(key); //衔接
        }
      }
    }
    //随机固定地形 医院之类
    //生成各种建筑个数
    let builds: number[] = this.getBuildIds();
    let ranBuildingLen = builds.length;
    while (ranBuildingLen > 0) {
      const i = builds.length - ranBuildingLen;
      let id: number = builds[i];

      // let ranIndex: number = Math.floor(ranData1.length * RandomTool.getRandom());
      let ranIndex: number = Math.floor(ranData1.length * RandomTool.getRandom());
      let ranKey: string = ranData1[ranIndex];

      let [ranXStr, ranYStr] = ranKey.split('_');
      let ranX = parseInt(ranXStr, 10);
      let ranY = parseInt(ranYStr, 10);

      let key2 = `${ranX + 1}_${ranY}`;
      let key3 = `${ranX + 1}_${ranY + 1}`;
      let key4 = `${ranX}_${ranY + 1}`;
      if (!randomRemain[key2] || !randomRemain[key3] || !randomRemain[key4]) {
        continue;
      }

      let needUnit: string[] = [ranKey];
      ranPool[ranKey].setType(id, 1);

      ranPool[key2].setType(id, 2);
      needUnit.push(key2);

      ranPool[key3].setType(id, 3);
      needUnit.push(key3);

      ranPool[key4].setType(id, 4);
      needUnit.push(key4);

      //去除这些
      for (let j: number = 0; j < needUnit.length; j++) {
        let k: string = needUnit[j];
        let ind: number = ranData1.indexOf(k);
        ranData1.splice(ind, 1);
        delete randomRemain[k];
        ind = ranData2.indexOf(k);
        if (ind >= 0) {
          ranData2.splice(ind, 1);
        }
      }
      ranBuildingLen--;
    }

    let ranData: string[] = ranData1.concat(ranData2);
    //随机障碍物
    //30个路障
    for (let i: number = 0; i < 30; i++) {
      let ranIndex: number = Math.floor(ranData.length * RandomTool.getRandom());
      let ranKey: string = ranData.splice(ranIndex, 1)[0];
      ranPool[ranKey].setType(MapUnitType.LuZhang);
    }
    //30个石头
    for (let i: number = 0; i < 30; i++) {
      let ranIndex: number = Math.floor(ranData.length * RandomTool.getRandom());
      let ranKey: string = ranData.splice(ranIndex, 1)[0];
      ranPool[ranKey].setType(MapUnitType.Stone);
    }
    //30个大树
    for (let i: number = 0; i < 30; i++) {
      let ranIndex: number = Math.floor(ranData.length * RandomTool.getRandom());
      let ranKey: string = ranData.splice(ranIndex, 1)[0];
      ranPool[ranKey].setType(MapUnitType.Tree);
    }
    this.canCreatePlayerPos = ranData;
  }

  public canCreatePlayerPos;

  public getDiffKey(key: string, x: number, y: number): string {
    let ns: string[] = key.split('_');
    let nx: number = parseInt(ns[0]) + x;
    let ny: number = parseInt(ns[1]) + y;
    return nx + '_' + ny;
  }

  /**
   *
   */
  public getBuildIds(): number[] {
    let buildData = [
      [BuildType.FrutShop, 3],
      [BuildType.Hospital, 2],
      [BuildType.EXRoom, 1],
      [BuildType.Shop_Eye, 2],
      [BuildType.Shop_Clock, 2],
      [BuildType.PostBox, 2],
      [BuildType.Shop_Mac, 1],
      [BuildType.OfficeBuild, 3],
      [BuildType.Pauper, 1],
    ];
    let ids: number[] = [];
    for (let i: number = 0; i < buildData.length; i++) {
      let id: number = buildData[i][0];
      let times: number = buildData[i][1];
      for (let j: number = 0; j < times; j++) {
        ids.push(id);
      }
    }
    return ids;
  }

  public getData(i, j): MapUnit {
    if (!this.mapData[i]) return null;
    return this.mapData[i][j];
  }
}
